package com.wdd.myplatform.controller.alipay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.wdd.myplatform.common.Result;
import com.wdd.myplatform.config.AlipayConfig;
import com.wdd.myplatform.config.DefaultAlipayClientFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Properties;

/**
 * 手机网站支付相关功能
 * 手机网页应用接入该能力后，用户在手机网站进行支付时，可通过浏览器唤起支付宝客户端进行付款，实现和App支付相同的支付体验。
 * 如用户没有安装支付宝客户端，则可以在网页端完成支付。
 * @author wdd 2022/5/20
 */
@Controller()
@RequestMapping("/aliPayController")
public class AliPayController {

    private String tradeNo = "20150320010101009";

    /**
     * 统一收单线下交易查询
     *
     */
    @GetMapping("/aliPayTradeQuery")
    @ResponseBody
    public Result aliPayTradeQuery(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws AlipayApiException {
        Result<AlipayTradeQueryResponse> result = new Result<AlipayTradeQueryResponse>();
        Properties prop = AlipayConfig.getProperties();

        //初始化请求类
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);
        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类
        AlipayTradeQueryModel alipayModel = new AlipayTradeQueryModel();
        alipayModel.setOutTradeNo(tradeNo);
        alipayRequest.setBizModel(alipayModel);
        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是接口服务，使用exexcute方法获取到返回值
            AlipayTradeQueryResponse alipayResponse = alipayClient.execute(alipayRequest);
            boolean success = alipayResponse.isSuccess();
            if(success){
                System.out.println("调用成功");
                String tradeStatus = alipayResponse.getTradeStatus();
                System.out.println(tradeStatus);
                //TODO 实际业务处理，开发者编写。可以通过alipayResponse.getXXX的形式获取到返回值
            } else {
                System.out.println("调用失败");
            }
            result.setSuccess(true);
            result.setResult(alipayResponse);
            return result;

        } catch (AlipayApiException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
                return result;
            }
        }
        return null;
    }

    /**
     * 手机支付创建订单并调用支付宝支付
     *
     */
    @GetMapping("/alipayTradeWapPay")
    public void alipayTradeWapPay(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws AlipayApiException {
        Result<AlipayTradeWapPayResponse> result = new Result<AlipayTradeWapPayResponse>();
        Properties prop = AlipayConfig.getProperties();

        String charset = prop.getProperty("CHARSET");

        //初始化请求类
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);

        alipayRequest.setNotifyUrl(prop.getProperty("NOTIFY_URL"));

        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类
        AlipayTradeWapPayModel tradeWapPayModel = new AlipayTradeWapPayModel();
        //商户网站唯一订单号
        tradeWapPayModel.setOutTradeNo(tradeNo);
        //订单总金额。单位为元，精确到小数点后两位，取值范围：[0.01,100000000]
        tradeWapPayModel.setTotalAmount("1.00");
        //订单标题
        tradeWapPayModel.setSubject("大乐透");
        //销售产品码，商家和支付宝签约的产品码。手机网站支付为：QUICK_WAP_WAY
        tradeWapPayModel.setProductCode("QUICK_WAP_WAY");
        //用户付款中途退出返回商户网站的地址
        tradeWapPayModel.setQuitUrl("http://www.baidu.com");
        alipayRequest.setBizModel(tradeWapPayModel);
        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是页面跳转类服务，使用pageExecute方法得到form表单后输出给前端跳转
            AlipayTradeWapPayResponse alipayResponse = alipayClient.pageExecute(alipayRequest);

            // 调用SDK生成表单
            String form = alipayResponse.getBody();
            httpResponse.setContentType("text/html;charset=" + charset);
            httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
            result.setSuccess(true);
            result.setResult(alipayResponse);

        } catch (AlipayApiException | IOException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
            }
        }
    }

    /**
     * 电脑网站支付创建订单并调用支付宝支付
     *
     */
    @GetMapping("/alipayTradePagePay")
    public void alipayTradePagePay(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws AlipayApiException {
        Result<AlipayTradePagePayResponse> result = new Result<AlipayTradePagePayResponse>();
        Properties prop = AlipayConfig.getProperties();
        String charset = prop.getProperty("CHARSET");

        //初始化请求类
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);

//        alipayRequest.setReturnUrl(prop.getProperty("RETURN_URL"));
        alipayRequest.setNotifyUrl(prop.getProperty("NOTIFY_URL"));

        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类
        AlipayTradePagePayModel tradePagePayModel = new AlipayTradePagePayModel();
        //商户网站唯一订单号
        tradePagePayModel.setOutTradeNo(tradeNo);
        //订单总金额。单位为元，精确到小数点后两位，取值范围：[0.01,100000000]
        tradePagePayModel.setTotalAmount("1.00");
        //订单标题
        tradePagePayModel.setSubject("大乐透");
        //销售产品码，与支付宝签约的产品码名称。注：目前电脑支付场景下仅支持FAST_INSTANT_TRADE_PAY
        tradePagePayModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizModel(tradePagePayModel);
        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是页面跳转类服务，使用pageExecute方法得到form表单后输出给前端跳转
            AlipayTradePagePayResponse alipayResponse = alipayClient.pageExecute(alipayRequest);

            // 调用SDK生成表单
            String form = alipayResponse.getBody();
            httpResponse.setContentType("text/html;charset=" + charset);
            httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
            result.setSuccess(true);
            result.setResult(alipayResponse);

        } catch (AlipayApiException | IOException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
            }
        }
    }

    /**
     * 统一收单交易退款接口
     * @param request
     * @param response
     * @param modelMap
     * @param alipayModel
     * @return
     */
    @PostMapping("/alipayTradeRefund")
    @ResponseBody
    public Object alipayTradeRefund(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, AlipayTradeRefundModel alipayModel){
        Result<AlipayTradeRefundResponse> result = new Result<AlipayTradeRefundResponse>();

        //初始化请求类
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);
        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类
        AlipayTradeRefundModel tradeRefundModel = new AlipayTradeRefundModel();
        tradeRefundModel.setOutTradeNo(tradeNo);
        tradeRefundModel.setRefundAmount("1.00");
        alipayRequest.setBizModel(tradeRefundModel);

        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是接口服务，使用exexcute方法获取到返回值
            AlipayTradeRefundResponse alipayResponse = alipayClient.execute(alipayRequest);
            if(alipayResponse.isSuccess()){
                System.out.println("调用成功");
                //TODO 实际业务处理，开发者编写。可以通过alipayResponse.getXXX的形式获取到返回值
            } else {
                System.out.println("调用失败");
            }
            result.setSuccess(true);
            result.setResult(alipayResponse);
            return result;

        } catch (AlipayApiException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
                return result;
            }
        }
        return null;
    }

    /**
     * 统一收单交易退款查询
     * @param request
     * @param response
     * @param modelMap
     * @param alipayModel
     * @return
     */
    @PostMapping(value="/alipayTradeFastpayRefundQuery")
    @ResponseBody
    public Object alipayTradeFastpayRefundQuery(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, AlipayTradeFastpayRefundQueryModel alipayModel){
        Result<AlipayTradeFastpayRefundQueryResponse> result = new Result<AlipayTradeFastpayRefundQueryResponse>();
        Properties prop = AlipayConfig.getProperties();

        //初始化请求类
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);
        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类
        AlipayTradeFastpayRefundQueryModel tradeFastpayRefundQueryModel = new AlipayTradeFastpayRefundQueryModel();
        tradeFastpayRefundQueryModel.setOutTradeNo(tradeNo);
        tradeFastpayRefundQueryModel.setOutRequestNo(tradeNo);

        alipayRequest.setBizModel(tradeFastpayRefundQueryModel);
        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是接口服务，使用exexcute方法获取到返回值
            AlipayTradeFastpayRefundQueryResponse alipayResponse = alipayClient.execute(alipayRequest);
            if(alipayResponse.isSuccess()){
                System.out.println("调用成功");
                //TODO 实际业务处理，开发者编写。可以通过alipayResponse.getXXX的形式获取到返回值
            } else {
                System.out.println("调用失败");
            }
            result.setSuccess(true);
            result.setResult(alipayResponse);
            return result;

        } catch (AlipayApiException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
                return result;
            }
        }

        return null;

    }

    /**
     * 统一收单交易关闭接口
     * 用于交易创建后，用户在一定时间内未进行支付，可调用该接口直接将未付款的交易进行关闭
     * @param request
     * @param response
     * @param modelMap
     * @param alipayModel
     * @return
     */
    @PostMapping(value="/alipayTradeClose")
    @ResponseBody
    public Object alipayTradeClose(HttpServletRequest request,HttpServletResponse response,ModelMap modelMap,AlipayTradeCloseModel alipayModel){
        Result<AlipayTradeCloseResponse> result = new Result<AlipayTradeCloseResponse>();
        Properties prop = AlipayConfig.getProperties();

        //初始化请求类
        AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);
        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类
        AlipayTradeCloseModel tradeCloseModel = new AlipayTradeCloseModel();
        tradeCloseModel.setOutTradeNo(tradeNo);
        alipayRequest.setBizModel(tradeCloseModel);
        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是接口服务，使用exexcute方法获取到返回值
            AlipayTradeCloseResponse alipayResponse = alipayClient.execute(alipayRequest);
            if(alipayResponse.isSuccess()){
                System.out.println("调用成功");
                //TODO 实际业务处理，开发者编写。可以通过alipayResponse.getXXX的形式获取到返回值
            } else {
                System.out.println("调用失败");
            }
            result.setSuccess(true);
            result.setResult(alipayResponse);
            return result;

        } catch (AlipayApiException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
                return result;
            }
        }
        return null;
    }

    /**
     * 查询对账单下载地址
     * 沙箱只能调用查询对账单下载地址接口，但是无法查看对账单，只有正式环境才可以，请使用正式环境调用查看
     * @param request
     * @param response
     * @param modelMap
     * @param alipayModel
     * @return
     */
    @PostMapping(value="/alipayDataDataserviceBillDownloadurlQuery")
    @ResponseBody
    public Object alipayDataDataserviceBillDownloadurlQuery(HttpServletRequest request,HttpServletResponse response,ModelMap modelMap,AlipayDataDataserviceBillDownloadurlQueryModel alipayModel){
        Result<AlipayDataDataserviceBillDownloadurlQueryResponse> result = new Result<AlipayDataDataserviceBillDownloadurlQueryResponse>();
        Properties prop = AlipayConfig.getProperties();

        //初始化请求类
        AlipayDataDataserviceBillDownloadurlQueryRequest alipayRequest = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        //添加demo请求标示，用于标记是demo发出
        alipayRequest.putOtherTextParam(AlipayConfig.ALIPAY_DEMO, AlipayConfig.ALIPAY_DEMO_VERSION);
        //设置业务参数，alipayModel为前端发送的请求信息，开发者需要根据实际情况填充此类

        AlipayDataDataserviceBillDownloadurlQueryModel billDownloadurlQueryModel = new AlipayDataDataserviceBillDownloadurlQueryModel();
        //trade：商户基于支付宝交易收单的业务账单；
        //signcustomer：基于商户支付宝余额收入及支出等资金变动的账务账单。
        billDownloadurlQueryModel.setBillType("trade");
        //示例值 2016-04-05
        billDownloadurlQueryModel.setBillDate("2022-05-26");
        alipayRequest.setBizModel(billDownloadurlQueryModel);
        //sdk请求客户端，已将配置信息初始化
        AlipayClient alipayClient = DefaultAlipayClientFactory.getAlipayClient();
        try {
            //因为是接口服务，使用exexcute方法获取到返回值
            AlipayDataDataserviceBillDownloadurlQueryResponse alipayResponse = alipayClient.execute(alipayRequest);
            if(alipayResponse.isSuccess()){
                System.out.println("调用成功");
                //TODO 实际业务处理，开发者编写。可以通过alipayResponse.getXXX的形式获取到返回值
            } else {
                System.out.println("调用失败");
            }
            result.setSuccess(true);
            result.setResult(alipayResponse);
            return result;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            if(e.getCause() instanceof java.security.spec.InvalidKeySpecException){
                result.setMessage("商户私钥格式不正确，请确认配置文件Alipay-Config.properties中是否配置正确");
                return result;
            }
        }
        return null;
    }

}
